{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn import preprocessing\n",
    "#数据是否需要标准化\n",
    "scale = False\n",
    "# 数据标准化：\n",
    "# 会使原模型图改变，但是能够提高梯度下降法的精确性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#载入数据\n",
    "data = np.genfromtxt(\"LR_testset.csv\",delimiter=',')\n",
    "x_data = data[:20,:-1]\n",
    "y_data = data[:20,-1]\n",
    "\n",
    "#画出分类模型的散点图\n",
    "def plot():\n",
    "    x0 = []\n",
    "    y0 = []\n",
    "    x1 = []\n",
    "    y1 = []\n",
    "    #切分不同类型的数据\n",
    "    for i in range(len(x_data)):\n",
    "        if y_data[i]==0:\n",
    "            x0.append(x_data[i,0])\n",
    "            y0.append(x_data[i,1])\n",
    "        else:\n",
    "            x1.append(x_data[i,0])\n",
    "            y1.append(x_data[i,1])\n",
    "    \n",
    "    #画图\n",
    "    scatter0 = plt.scatter(x0,y0,c='b',marker='o')\n",
    "    scatter1 = plt.scatter(x1,y1,c='r',marker='x')\n",
    "    #画图例\n",
    "    plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best')\n",
    "    \n",
    "plot()\n",
    "plt.show()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(20, 2)\n",
      "(20, 1)\n",
      "(20, 3)\n"
     ]
    }
   ],
   "source": [
    "#数据处理,添加偏置项\n",
    "x_data = data[:20,:-1]\n",
    "y_data = data[:20,-1,np.newaxis]\n",
    "\n",
    "print(np.mat(x_data).shape)\n",
    "print(np.mat(y_data).shape)\n",
    "#给样本添加偏置项\n",
    "X_data = np.concatenate((np.ones((20,1)),x_data),axis=1)\n",
    "print(X_data.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "#sigmoid函数\n",
    "def sigmoid(x):\n",
    "    return 1.0/(1.0 + np.exp(-x))\n",
    "\n",
    "#代价函数\n",
    "def cost(xMat,yMat,ws):\n",
    "    left = np.multiply(yMat,np.log(sigmoid(xMat * ws)))\n",
    "    right = np.multiply(1 - yMat, np.log(1 - sigmoid(xMat * ws)))\n",
    "    return np.sum(left + right) / -(len(xMat))\n",
    "\n",
    "#梯度下降法\n",
    "def gradAscent(xArr,yArr):\n",
    "    \n",
    "    if scale == True:\n",
    "        xArr = preprocessing.scale(xArr)\n",
    "    xMat = np.mat(xArr)\n",
    "    yMat = np.mat(yArr)\n",
    "    \n",
    "    lr = 0.001\n",
    "    epochs = 10000\n",
    "    costList = []\n",
    "    #计算数据行列数\n",
    "    #行代表数据个数\n",
    "    #列代表权值个数\n",
    "    m,n = np.shape(xMat)\n",
    "    #初始化权值\n",
    "    ws = np.mat(np.ones((n,1)))\n",
    "    \n",
    "    for i in range(epochs + 1):\n",
    "        #xMat和weights矩阵相乘\n",
    "        h = sigmoid(xMat * ws)\n",
    "        ws_grad = xMat.T * (h - yMat)/m\n",
    "        ws = ws - lr * ws_grad\n",
    "        \n",
    "        if i % 50 ==0:\n",
    "            costList.append(cost(xMat,yMat,ws))\n",
    "    return ws,costList"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.        ]\n",
      " [-0.26505287]\n",
      " [ 0.43149425]]\n"
     ]
    }
   ],
   "source": [
    "#训练模型，得到权值和cost值得变化\n",
    "ws , costList = gradAscent(X_data,y_data)\n",
    "print(ws)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "if scale ==False:\n",
    "    #画图决策边界\n",
    "    plot()\n",
    "    x_test = [[0],[1]]\n",
    "    #求y_test：\n",
    "#     令w0 + x1*w1 + x2*w2 = 0\n",
    "#     x1与x2的关系即为所求图像直线\n",
    "    y_test = (-ws[0] - x_test * ws[1]) / ws[2]\n",
    "    plt.plot(x_test,y_test,'k')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#画图 loss 值的变化\n",
    "x = np.linspace(0,10000,201)\n",
    "plt.plot(x,costList,c = 'r')\n",
    "plt.title('Train')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Cost')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "             precision    recall  f1-score   support\n",
      "\n",
      "        0.0       0.60      0.55      0.57        11\n",
      "        1.0       0.50      0.56      0.53         9\n",
      "\n",
      "avg / total       0.55      0.55      0.55        20\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#预测\n",
    "def predict(x_data,ws):\n",
    "    if scale == True:\n",
    "        x_data = preprocessing.scale(x_data)\n",
    "    xMat = np.mat(x_data)\n",
    "    ws = np.mat(ws)\n",
    "    return [1 if x>=0.5 else 0 for x in sigmoid(xMat*ws)]\n",
    "precisions = predict(X_data,ws)\n",
    "\n",
    "print(classification_report(y_data,precisions))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
